//先载入一个模块配置文件，成功后，再载入需要的模块
//Common中包含了一些通用函数，比如判断js文件是否存在等。
//注意Element中define(['vue']),所以对vue引用不能使用首字大写

//搜索项标签功能
  //显示默认标签,从searItem中获得默认值*
    //从sesssion中获得默认值
  //cloForKey形成标签,每次新得选择是叠加,不是替换
  //高级搜索确认后刷新标签,可能会和colForKey重复 *
  //根据标签从后台获取数据
  //select单选,多选 popupselect checkbox等标签显示文字的问题
 
require(['Resource/Script/requireJs/_require.config.js?v='+Math.random()],function(){
  require(['vue','Common','axios','xlsx','RowEditButtonFuncs'],function(vue,Common,axios,XLSX,RowEditButtonFuncs){
    var title=varTemplate.title || "列表";
    var columns = varTemplate.arr_field_info;
    // var action = "<{$action}>";
    var action = varTemplate.actionLoadData;
    var textAfterPage = varTemplate.textAfterPage||'';
    // var searchItems = varTemplate.searchItems;
    var menuRightTop = varTemplate.menuRightTop||[];
    // //关键自匹配字段
    var colsForKey = varTemplate.colsForKey||[];
    var multiSelect = varTemplate.multiSelect||false;
    var optExpand = varTemplate.optExpand;

    //回调函数的集合
    var callbacks = [];

    var opt = {
      el: '#div1',
      data : function() {
        //如果 colsForKey 为空,从columns中获取
        if(colsForKey.length==0) {
          for(var k in columns) {
            var item=columns[k];
            if(item.forKeySearch) {
              colsForKey.push({'text':item.text,'col':k});
            }
          }
        }
        //默认显示所有列
        var colNamesShow=[];
        var editButtons = [];
        for(var k in columns) {
          columns[k].show=true;
          colNamesShow.push(k);
          //如果显示操作按钮,保证最小宽度为130
          if(columns[k].showButton) {
            if(columns[k].width!=='') columns[k].width=130;
            else {
              columns[k].width = columns[k].width>130 ? columns[k].width : 130;
            }
            editButtons = columns[k].editButtons;
          }
        }
        //将 editButtons 分解成两个部分,前3个一组默认显示,后面的以dropdown呈现
        var defaultEditButtons = [];
        var moreEditButtons = [];
        editButtons.forEach((item,i)=>{
          if(i<3) defaultEditButtons.push(item);
          else {
            moreEditButtons.push(item);
          }
        });

        //将 menuRightTop 分解,第一个单独形成按钮
        // var addUrl = <{$addUrl|@json_encode}> ||'';
        var addUrl = '';
        var buttonRightTop = addUrl!='' ? {text:'新增',url:addUrl,icon:'el-icon-circle-plus'} : menuRightTop.splice(0,1)[0];
        // dump(varTemplate);
        return {
          title:title,
          //当前页码
          'currentPage':1,
          //每页记录数
          'pagesize':varTemplate.pagesize || 20 ,
          //记录总数
          'total':0,
          //排序字段
          sortBy:'',
          //升序或者降序
          sortOrder:'',
          //右上角的更多菜单
          'menuRightTop':menuRightTop,
          //右上角第一个按钮
          'buttonRightTop':buttonRightTop,
          //右上角按钮图标集合
          'menuRightTopIcon':['el-icon-tickets','el-icon-document','el-icon-goods','el-icon-sold-out','el-icon-news','el-icon-message','el-icon-date','el-icon-printer','el-icon-time','el-icon-bell'],
          //搜索关键字
          'key':'',
          //高级搜索关键字
          // 'advParams':{},
          //关键字可匹配的字段集合
          'colsForKey':colsForKey,
          //关键字输入后选中的匹配字段
          'colForKey':{},
          //高级搜索弹框需要的formItem
          'searchItems':varTemplate.searchItems,
          //高级搜索弹窗是否弹开过
          'searchDialogOpened':false,
          //是否显示载入
          'isLoading':true,
          //数据集合
          'rows':[],
          //是否需要选择
          'multiSelect':multiSelect,
          //本页选中记录
          'multipleSelection':[],
          //获取数据的远程地址
          'action':action,
          //从后台获取数据时需要带入的参数
          // 'params':{},
          //数据表对应的字段
          'columns':columns,
          //需要显示的列
          'colNamesShow':colNamesShow,
          //详细展开面板配置
          'optExpand':optExpand,
          //展开面板对应的组件,决定展开面板的展示效果,可设置为用户自定义的comp todo
          // 'compExpand':compExpand || 'comp-expand-form',
          'textAfterPage':textAfterPage,
          //每行中的高级功能按钮
          'editButtons':editButtons,
          'defaultEditButtons':defaultEditButtons,
          'moreEditButtons':moreEditButtons,
          //dropdown-men是否显示,dropdown显示时,不隐藏菜单
          'showDropdown':false,
          //当前显示dropdown的是第几行
          'showDropdownIndex':-1,
          //每行功能按钮的可用图标
          'defaultEditButtonsIcons':['el-icon-edit','el-icon-delete','el-icon-edit-outline'],

          //所有表单元素的自定义事件的回调集合
          'callbacks':callbacks,
          //用户自定义插槽
          'otherComps':[],
          //每行记录的操作按钮的自定义组件
          'compsRowEdit':[],
          //是否载入状态
          'showLoading':true,
          //新增记录的url
          //'addUrl' : addUrl,
          //新增按钮图标
          //'iconAdd': addUrl=='' ? "el-icon-menu":"el-icon-circle-plus",
          //导出进度百分比
          'exportPercentag':0,
          //全部导出时获取数据地址
          'actionExportAll':varTemplate.actionExportAll,
          'rowKey':varTemplate.rowKey || 'id',
          //是否显示合计行
          'showSummary':varTemplate.showSummary,
          //搜索匹配项
          // 'searchTags':[
          //   {title:'业务员',value:'张三',connector:':',linked:[filterTag]},
          //   {title:'订单日期',value:['2020年2月9日','2020年2月9日'],connector:':'},
          //   {title:'公司名',value:'常州',connector:'包含'},
          // ],
          'searchTags':[],
          //搜索项的数据模型，根据此模型改变快速搜索，搜索弹框，searchTags, 表头筛选项,
          //{key:'compName',value:'张三',inAdvSearchDialog:bool,inSearchTags:bool,inQuickSearch:bool}
          'searchModel':[],
          //搜索项对应的文字索引，比如tarderId=1时需要显示张三
          'mapSearchTagText' : {
            'depId':'开发部',
            'traderId':'张三,李四',
            'productId':'色织',
            'clientId':'易奇',
          },
        }
      },
      //注入一个穿透变量
      provide : function() {
        return {
          mapSearchTagText : this.mapSearchTagText,
        }
      },
      methods: {
        //测试方法
        test : function() {
          dump(this);
        },
        //筛选条件改变后的动作，一般是从后台重新拿数据
        handleFilterChange : function(filters) {
          let temp = {};
          let key;
          let val;
          for(let k in filters) {
            key = k;
            val = filters[k][0]||'';
          }
          temp[key] = Object.assign(this.searchModel[key],{
            key:key,
            value:val,
            text:this.columns[key].text,
            inSearchTags:true,
          });
          this.searchModel = Object.assign({},this.searchModel,temp);

          //如果需要，清空快速搜索
          // if(this.colForKey.col==key) {
          //   this.colForKey={};
          // }
        },

        //表格组件挂载后触发
        onTableMount: function(){
          dump('onTableMount fired');
          this.$refs.tbl.multiSelect=this.multiSelect;

          //设置是否显示操作列
          if(this.editButtons.length>0) {
            this.$refs.tbl.showEditColumn=true;
          }
          if(this.optExpand!=null) {
            this.$refs.tbl.showExpand=true;
          }

          this.setTblHeight();

          // window.tbl = this.$refs.tbl;
        },

        setTblHeight : function() {
          var bodyHeight = document.documentElement.clientHeight || document.body.clientHeight;
          this.$nextTick(()=>{
            this.$refs.tbl.setHeight(bodyHeight-90);
          });
        },

        //其他组件挂载后触发
        onOtherCompMount : function(comp){
          // debugger;
        },
        //行编辑按钮自定义组件装载时触发
        onCompsRowEditMount:function(comp) {
          dump('onCompsRowEditMount');
          //装载完成自动触发 handelClick
        },
        //从服务器获得高级搜索弹框表单项后后触发,设置tags
        //该事件发生在tablemount之后，
        onSearchDialogMountItems: function(advDialog){
          // return;
          dump('onSearchDialogMountItems fired');
          //根据后台返回的字段定义，修改searModel和seachTags的标题
          //这里是不需要重新加载数据的，所以不用 Object.assign,避免触发重新载入
          let advSearchItems = advDialog.searchItems;
          // let mapSearchItems = {};
          for(let k in advSearchItems) {
            let val = advSearchItems[k];
            let key = val.name;
            if(this.searchModel[key]) {
              this.searchModel[key].inAdvSearchDialog = true;
              this.searchModel[key].inSearchTags = true;
            }
            // mapSearchItems[key] = null;
            if(this.searchModel[key] && this.searchModel[key].inLocalStorage) {
              //如果是从localstorage中取得不需要处理
              continue;
            }

            let text =val.title;
            this.searchModel[key].text=text;

            //如果搜索项是select或者弹出选择，标签的内容需要进行转换，比如业务员不能显示id,必须名字
            this.searchModel[key].valueDesc = advDialog.getItemDesc(key,this.searchModel[key].value);
          }

          //确认searchModel中 inAdvSearchDialog=true的项,在高级弹窗中都存在
          // let keyForHide=[];
          // // dump(advSearchItems);
          // for(let k in this.searchModel) {
          //   if(this.searchModel[k].inAdvSearchDialog && !Common.isset(mapSearchItems,k)) {
          //     this.searchModel[k].inAdvSearchDialog = false;
          //     this.searchModel[k].inSearchTags = false;
          //     //还原searchModel中的值
          //     // this.searchModel[k].value=varTemplate.searchItems[k];
          //     keyForHide.push(k);
          //   }
          // }
          // dump(this.searchModel);
          // let temp = [];
          let mapTag = {};
          for(let i=0;this.searchTags[i];i++) {
            let key = this.searchTags[i].key;
            mapTag[key] = true;
            this.searchTags[i].title=this.searchModel[key].text;
            this.searchTags[i].valueDesc=this.searchModel[key].valueDesc;
            //确保标签中的每项都是有效的,
            // if(keyForHide.indexOf(key)==-1) {
            //   temp.push(this.searchTags[i]);
            // }
          }

          //补齐searchTag
          for(var k in this.searchModel) {
            if(mapTag[k]) continue;
            let v = this.searchModel[k];
            if(!v.value) continue;
            if(Array.isArray(v.value) && v.value.length==0) continue;
            if(!v.inSearchTags) continue;
            this.searchTags.push({
              key:k,
              title:v.text,
              connector:':',
              value:v.value,
              valueDesc:v.valueDesc
            });
          }
          this._setSearchFromLocal();
        },
        //新增记录按钮点击后触发
        // 'handleAdd' : function() {
        //   if(this.addUrl=='') return;
        //   window.location.href=this.addUrl;
        // },
        //-------------------数据相关-------------------
        //通过ajax请求从服务器获得数据
        //p:搜索带入的参数,
        _getRows : function() {
          var that = this;
          that.showLoading = true;
          let params={
            pagesize : this.pagesize,
            currentPage : this.currentPage,
            sortBy : this.sortBy,
            sortOrder : this.sortOrder,
          };
          // dump(this.searchModel);
          for(let k in this.searchModel) {
            if(!this.searchModel[k].value) continue;
            params[k] = this.searchModel[k].value;
          }
          // dump(this.searchModel);

          //参数统一从searchTags中获得，同时加入pagesize等
          dump('_getRows fired,params:',params);
          this.$http.post(this.action, params)
          .then((response)=> {
            // dump('load table data over');
            var data = response.data;
            var rows = response.data.rows;
            this.total = response.data.total;
            this.rows = rows;
            this.showDropdownIndex = -1;
            //如果没有rowkey(id),补充rowkey字段,
            var temp=[];
            for(var i=0;rows[i];i++) {
              temp.push(rows[i][this.rowKey]);
              if(rows[i][this.rowKey]==undefined) {
                if(i==0) {
                  console.warn('返回的数据集中未包含id字段,系统自动填充id字段,这可能会导致修改删除操作异常!');
                }
                rows[i][this.rowKey]=i+1;
              }
            }
            //以下是es6判断数组是否有重复值的方法,可能有些浏览器不一定兼容
            if((new Set(temp)).size != temp.length) {
              console.warn('rowKey重复,数据集中发现rowkey重复的记录,可能需要指定其他的字段为rowkey');
            }
            //检查rowkey字段是否有重复
            // this.isLoading = false;
            // this.showLoading = false;
            this.$refs.tbl.rows=this.rows;

            //设置合计行内容
            if(data.rowHeji) {
              this.$refs.tbl.setSummaries(data.rowHeji);
            }

            //渲染后重新布局，解决表头错位的问题
            this.$nextTick(()=>{
              setTimeout(()=>{
                that.showLoading = false;
                //重新渲染布局，避免合计行被遮挡住
                that.$refs.tbl.$refs.table.doLayout();
              },100);
            });
          })
          .catch((error)=>{
            this.$notify.warning({
              title : '错误',
              message:'数据获取出错'
            });
            // this.isLoading = false;
            // this.showLoading = false;
            console.log(error);
          });
        },
        //点击选中select
        handleUserSelect(selection,row) {
          this.multipleSelection = selection;
        },
        //点击全选select
        handleUserSelectAll(selection) {
          this.multipleSelection = selection;
        },
        //排序触发
        //如果为空函数,只对本页排序,不发起服务器请求,
        handleSortChange: function(column, prop, order) {
          if(column.sortable=='custom') {
            this.sortBy = prop;
            this.sortOrder = order;
            this.showLoading = true;
            this._getRows();
          }
        },
        //行点击时,隐藏其他行的dropdown,然后显示当前行的dropdow
        handleRowClick : function(row, event, column) {
          if(!this.showDropdown) return;
          //隐藏之前显示的dropdown-menu
          if(this.rows[this.showDropdownIndex]) {
            this.rows[this.showDropdownIndex]['__showButton'] = false;
          }
          // dump(this,this.showDropdownIndex);
          if(!row.hasOwnProperty('__showButton')) {
            vue.set(row,'__showButton',true);
          } else {
            row.__showButton = true;
          }
        },
        //鼠标移上显示操作按钮
        handelMouseOverRow : function(row, column, cell, event) {
          //如果有dropDown打开,直接返回
          if(this.showDropdown) return;
          //隐藏之前显示的dropdown-menu
          if(this.rows[this.showDropdownIndex]) {
            this.rows[this.showDropdownIndex]['__showButton'] = false;
          }
          if(!row.hasOwnProperty('__showButton')) {
            vue.set(row,'__showButton',true);
          } else {
            row.__showButton = true;
          }
        },
        //鼠标移出隐藏操作按钮
        handelMouseLeaveRow : function(row, column, cell, event) {
          if(this.showDropdown) return;
          row.__showButton = false;
        },
        //每行的编辑菜单项选中
        handleRowCommand(command) {
          var btn = command.btn;
          var row = command.row;
          RowEditButtonFuncs[btn.type].apply(this,[row,btn.options||{}]);
          return;
        },

        //-------------------高级搜索相关-----------------------
        //高级搜索内容是否都为空
        hasAdvParams : function() {
          //如果高级搜索弹框没有初始化，不显示
          if(this.searchDialogOpened===false) return false;
          for (var k in this.advParams) {
            if(this.advParams[k]!='') return true;
          }
          return false;
        },
        //高级搜索项的文字描述
        // getDescAdvParams : function() {
        //   var text=[];
        //   this.$refs.advSearchDialog.searchItems.forEach((item,index)=>{
        //     var textJoin = item.type=='comp-text' ? "包含" : "等于";
        //     if(this.advParams[item.name]===undefined) return;
        //     if(this.advParams[item.name]=='') return;
        //     text.push(`${item.title} ${textJoin} ${this.advParams[item.name]}`)
        //   });
        //   return text.join("<br/>");
        // },
        //高级搜索弹框点击确认后搜索
        handleAdvSearchOk : function(params) {
          //将搜索条件保存到session中
          // var url = `?controller=${varTemplate.controller}&action=SaveSessionSearch`;
          // var param=params;
          // param.controller=varTemplate.controller;
          // param.action=varTemplate.action;
          // this.$http.post(url,param).then((response)=>{
          //   if(!response.data.success) {
          //     console.warn(response.data.msg);
          //     return;
          //   }
          //   dump('session保存成功');
          // }).catch((error)=>{
          //   dump(error);
          // });


          // this.key = '';
          this.currentPage=1;
          // this.showLoading = true;

          //修改searchModel
          // dump(params);return;
          let temp = {};
          for(let k in params) {
            if(!Common.isset(this.searchModel,k)) continue;
            let val = params[k];
            temp[k] = Object.assign(this.searchModel[k]||{},{
              //因为高级搜索都是从后台来的，所这里除了value外其他都不需要定义了。
              // key:k,
              // text:'高级搜索'+k,
              // inAdvSearchDialog:true,
              value:val,
            });
          }
          // dump(temp)
          this.searchModel = Object.assign({},this.searchModel,temp);
        },
        //关键字录入后的显示待匹配的字段
        querySearch(queryString, cb) {
          var ret = this.colsForKey || [];
          ret.map((item,i)=>{
            item.value=queryString;
          });
          cb(ret);
        },
        //关键字输入后选中匹配字段后触发
        handleKeywordSelect : function(val) {
          // dump('handleKeywordSelect fired');
          //将之前得colForKey关联得searchModel置空
          let keyOld = this.colForKey.col;
          if(keyOld) {
            this.searchModel[keyOld].value='';
            this.searchModel[keyOld].valueDesc='';
          }

          var k = val.col  || this.colsForKey[0].col;
          this.currentPage=1;
          val.col = k;          

          this.colForKey=val;
          if(this.searchModel[k] && this.searchModel[k].inColFilter) {
            this.$refs.tbl.clearFilter(k);
          }
          let temp ={};
          temp[k] = Object.assign(this.searchModel[k]||{},{
            key:k,
            value:val.value,
            text:this.columns[k] ? this.columns[k].text : val.text,
            inQuickSearch:true,
            inSearchTags:true,//高级搜索中的选项肯定也要出现在searchtag中
          });
          this.searchModel = Object.assign({},this.searchModel,temp);
        },
        //高级搜索点击
        openAdvanceSearch : function() {
          //显示高级搜索弹框
          this.$refs.advSearchDialog.show();
        },

        //导出本页
        //如果使用 FileSaver.js 就不要同时使用以下函数
        _saveAs:function(obj, fileName) {//当然可以自定义简单的下载文件实现方式
            var tmpa = document.createElement("a");
            tmpa.download = fileName || "下载";
            tmpa.href = URL.createObjectURL(obj); //绑定a标签
            tmpa.click(); //模拟点击实现下载
            setTimeout(function () { //延时释放
                URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
            }, 100);
        },
        //导出位excel的通用方法
        //rows为数据集,字段和this.columns不一定匹配
        _exportExcel : function(rows,fileName) {
          // dump(XLSX);
          var fName = fileName || "data.xlsx";
          var data = [];
          //表头处理
          var temp = [];
          for(var k in this.columns) {
            var col = this.columns[k];
            temp.push(col.text);
          }
          data.push(temp);

          //内容
          rows.forEach((item,i)=>{
            var temp = [];
            for(var k in this.columns) {
              var _tmpCellTxt = item[k] ? this.delHtmlTag(item[k]) : item[k];
              temp.push(_tmpCellTxt);
            }
            data.push(temp);
          });
          var ws = XLSX.utils.aoa_to_sheet(data);
          var wb=XLSX.utils.book_new();
          wb.SheetNames.push('sheet1');
          wb.Sheets['sheet1'] = ws;
          var wopts = { bookType:'xlsx', bookSST:false, type:'array' };
          var wbout = XLSX.write(wb,wopts);
          this._saveAs(new Blob([wbout],{type:"application/octet-stream"}), fName);
        },
        delHtmlTag : function(str){
          return typeof(str)=='string' ? str.replace(/<[^>]+>/g,"") : str;
        },
        //导出当前页,
        handleExport : function(){
          this.exportPercentag=0;
          setTimeout(()=>{
            this.exportPercentag=100;
            this._exportExcel(this.rows,`${this.title}${this.currentPage}.xlsx`);
          },500);

        },
        //导出全部
        handleExportAll: function(){
          //记录总数
          var total=this.total;
          // var total=1000;
          //每次请求条数
          var pagesize=200;
          //访问地址
          var url = this.actionExportAll;
          if(!url) {
            console.error("未发现smarty模版变量$actionExportAll,无法使用导出全部功能!");
            return false;
          }
          //成功请求次数
          var completeCount = 0;
          //设置当前进度百分比为0
          this.exportPercentag = 0;
          //Promise.all要用到的参数, 存放每次请求的Promise对象
          var funcs=[];
          //this指针
          var _this = this;
          //需要请求的次数
          var times = Math.ceil(total/pagesize);

          var params={
            sortBy : _this.sortBy,
            pagesize : pagesize,
            sortOrder : _this.sortOrder,
          };
          // dump(this.searchModel);
          for(let k in _this.searchModel) {
            if(!_this.searchModel[k].value) continue;
            params[k] = _this.searchModel[k].value;
          }

          for(let i=0;i<times;i++) {
            var param = Object.assign({currentPage:i+1},params);
            var func = new Promise(function(resolve, reject){
              _this.$http.post(url,param).then(function(response){
                var rows = response.data.rows;
                //完成百分比
                completeCount++;
                _this.exportPercentag=(100*completeCount/times).toFixed(2);
                // console.log(_this.exportPercentag);
                return resolve(rows);
              });
            });
            funcs.push(func);
          }

          //ajax请求全部完毕后进行导出
          Promise.all(funcs).then(function(values){
            var rows=[];
            //将数据合并
            for (var i=0; i<values.length; i++) {
                for (var j=0; j<values[i].length; j++) {
                    rows.push(values[i][j]);
                }
            }
            _this._exportExcel(rows,`${_this.title}${_this.currentPage}-all.xlsx`);
          });
        },
        //刷新
        handleRefresh : function() {
          this.showLoading = true;
          this._getRows();
        },

        //---------------------分页相关-----------------
        //页数改变时重新载入数据
        handleSizeChange :function(size) {
          this.currentPage=1;
          this.pagesize=size;
          this.showLoading = true;
          this._getRows();
        },
        //点击分页导航时重新载入数据
        handleCurrentChange : function(page) {
          this.currentPage=page;
          this.showLoading = true;
          this._getRows();
        },

        //-------------------高级功能相关---------------
        //右上角菜单点击后触发
        handleCommand : function(item) {
          // dump(item);return;
          var key = `${item.name}:click`;
          if(this.$root.callbacks[key]){
            this.$root.callbacks[key].apply(this,arguments);
          }else if(item.url){
            window.location.href = item.url;
          }
        },

        //注册用户自定义组件
        makeNewComp : function(opt) {
          //避免重复插入
          var found = false;
          for(var i=0;this.otherComps[i];i++) {
            if(this.otherComps[i].type==opt.type) {
              found = true;
              break;
            }
          }
          if(!found) {
            this.otherComps.push(opt);
          }

          //如果注册的是一个dialog组件,以下代码可能会报错,因为dialog的实例会在第一次显示的才创建
          this.$nextTick(()=>{
            return this.$refs[opt.name][0];
          });
          // console.log(this.$refs[opt.name]);
        },

        //对当前地址进行分解
        resolveUrl() {
          var pathName = window.document.location.pathname;
          var projectName = pathName.substring(1,pathName.substr(1).indexOf('/'), 1);

          var reg = new RegExp("(^|&)" + "controller" + "=([^&]*)(&|$)", "i");
          var r = window.location.search.substr(1).match(reg);
          var controller = unescape(r[2]);

          var reg = new RegExp("(^|&)" + "action" + "=([^&]*)(&|$)", "i");
          var r = window.location.search.substr(1).match(reg);
          var action = unescape(r[2]);
          return {
            projectName:projectName,
            controller:controller,
            action:action,
          }
        },

        //对localstorage的读写
        saveColsToLocal: function(cols) {
          let arr = this.resolveUrl();
          var json = JSON.stringify(cols);
          var stor = window.localStorage;
          stor.setItem(`${arr.projectName}-${arr.controller}-${arr.action}-cols`,json);
        },
        //从localstorage中读取可见列
        getColsFromLocal: function() {
          let arr = this.resolveUrl();
          var json = window.localStorage.getItem(`${arr.projectName}-${arr.controller}-${arr.action}-cols`);
          var cols = JSON.parse(json);
          return cols;
        },

        //清楚所有检索项
        clearTags : function() {
          //this.$refs.tbl.clearFilter();
          for(let k in this.searchModel) {
            let val = this.searchModel[k];
            if(!val.inSearchTags) continue;
            this.searchModel[k].value='';
          }
          this.searchModel = Object.assign({},this.searchModel);

        },
        //关闭某个检索项
        closeTag : function(key) {
          this.searchModel[key].value='';
          this.searchModel = Object.assign({},this.searchModel);
        },
        //根据标签对象获得标签文字
        getTagText : function(tag) {
          // dump(tag.key,tag.value);
          if(tag.valueDesc) return `${tag.title}${tag.connector}${tag.valueDesc}`;
          var v = tag.value;
          if(Array.isArray(v)) {
            v= v[0]+'至'+v[1];
          }
          return `${tag.title}${tag.connector}${v}`;
        },

        //从 后台传入的 searchItems 设置初始
        initSearchModel : function() {
          this.searchModel = [];

          //后台传入的搜索条件
          for(let k in varTemplate.searchItems) {
            let val = varTemplate.searchItems[k] || '';
            if(val.value) val=val.value;
            else {
              if(typeof(val)=='object' && !Array.isArray(val)) val="";
            }
            let temp = {
              key:k,
              value:val,
              text:'后台配置'+k,
              // inAdvSearchDialog:false,
              // inSearchTags:false,
              sourceRemote:varTemplate.searchItems[k],
            };

            this.searchModel[k] = temp;
          }
          //表头定义中可能设置了筛选条件
          for(let k in this.columns) {
            let col = this.columns[k];
            if(!col.otherProps) continue;
            //判断是否存在列的筛选项
            let temp = {
              key:k,
              value:col.otherProps.filteredValue?col.otherProps.filteredValue[0]:'',
              text:col.text,
              inColFilter:true,
              inSearchTags:true,//高级搜索中的选项肯定也要出现在searchtag中
            };
            // dump(k,col.otherProps);
            this.searchModel[k] = Object.assign(this.searchModel[k]||{},temp);
          }

          //localstorage中载入搜索条件,优先级最高，

          //此时 keyAppend 的 inSearchTags 和 inAdvSearchDialog 都是true,
          //通过下面的代码后,value会变成'',
          // debugger;
          //_getRows 在 onSearchDialogMountItems 之前触发
          //如何知道 keyAppend 的 inSearchTags 和 inAdvSearchDialog 应该改变?
          if(!varTemplate.ignoreSearchCache) {
            this._loadSearchFromLocal();
          } else {            
            dump('ignoreSearchCache is true,不缓存');
          }
          // dump(this.searchModel['aa']);
          dump('initSearchModel fired',this.searchModel);
        },
        //从本地存储中获得搜索条件
        //如果是popup-select控件（productId),改变后，初次载入时无法获得正确的描述
        //保存到localstorage时保留一个特殊的属性，取得时从localstorage中获得
        //高级弹窗中的值不能正确显示
        _loadSearchFromLocal() {
          let arr = this.resolveUrl();
          let key = `${arr.projectName}-${arr.controller}-${arr.action}-search`;
          let jsonObj = JSON.parse(window.localStorage.getItem(key));　
          let thisDay = Common.getDate();

          for(let k in jsonObj) {
            if(jsonObj[k].dateSave!=thisDay) {
              continue;
            }
            if(!this.searchModel[k]) {              
              //存在高级弹窗中没有,但是colForKey中存在的情况,不能跳过
              // continue;
            }
            let obj=jsonObj[k];

            //改变searchItem得默认值
            if(Common.isset(this.searchItems,k)) {
              if(Common.isset(this.searchItems[k],'value')) {
                this.searchItems[k].value = obj.value;
              } else {
                this.searchItems[k] = obj.value;
              }              
            }
            if(this.searchItems[k] && this.searchItems[k].text) {
              this.searchItems[k].text=obj.valueDesc;
            }
            let temp = {
              // key:k,
              value:obj.value,
              valueDesc:obj.valueDesc,
              text:obj.title,
              // title:obj.title,
              inLocalStorage:true,
              inSearchTags:true,
            };
            this.searchModel[k] = Object.assign(this.searchModel[k]||{},temp);
            // dump(this.searchModel[k]);
          }
        },
        //将搜索条件保存到本地存储中
        _setSearchFromLocal() {
          // return;
          let thisDay = Common.getDate();
          let arr = this.resolveUrl();
          let key = `${arr.projectName}-${arr.controller}-${arr.action}-search`;

          let temp={};
          // dump(this.searchTags);
          for(let tag of this.searchTags) {
            temp[tag.key] = {
              value:tag.value,
              valueDesc:tag.valueDesc,
              title:tag.title,
              dateSave:thisDay,
            };
          }
          //需要设置有效期为1天 to do
          // dump('set local',key,temp);
          window.localStorage.setItem(key,JSON.stringify(temp));　
        },

      },
      computed: {
        searchTagsShow : function() {
          var ret = [];
          for(let v of this.searchTags) {
            if(Common.isEmpty(v.value)) continue;
            ret.push(v);
          }
          return ret;
        }
      },
      watch : {
        //可显示列变化
        'colNamesShow' : function(val,oldVal) {
          this.saveColsToLocal(val);
          //将需要显示的列存入localstorage
          for(var i=0;val[i];i++) {
            if(!this.columns[val[i]]) continue;
            this.columns[val[i]].show = true;
          }
          for(var k in this.columns) {
            if(val.indexOf(k)==-1) {
              this.columns[k].show = false;
            }
          }
          //
          this.$nextTick(()=>{
            this.$refs.tbl.$refs.table.doLayout();
          });
        },

        //searchTag改变时，触发快速搜索，高级搜索，表头筛选的变化
        'searchModel' : {
          handler: function(val,oldVal) {
            // dump('watch searchModel fired',val);

            //设置快速搜索，如果需要，进行清空
            if(this.colForKey.col) {
              let key = this.colForKey.col;
              this.colForKey.value= this.searchModel[key].value;
              this.key = this.colForKey.value;
            }

            // if(this.searchModel[k])
            // this.key='';

            let ret = [];
            for(let k in this.searchModel) {
              let val = this.searchModel[k];
              //清除表头filter
              if(val.inColFilter) {
                if(!val.value) this.$refs.tbl.clearFilter(k);
              }

              //设置高级搜索的表单项
              //关闭productId的搜索标签，期望弹框中的productId置空，todo
              if(val.inAdvSearchDialog) {
                if(this.$refs.advSearchDialog) {
                  // if(k=='productId') {
                  //   dump(`change productId to `,val,typeof(val.value));
                  //   dump('searchModel',this.searchModel,' val.value is',val.value)
                  // }
                  // dump(k,this.$refs.advSearchDialog);
                  this.$refs.advSearchDialog.setItem(k,val.value);
                }
              }

              //设置筛选标签
              if(!val.inSearchTags) continue;
              // if(!val.value) continue;
              // if(Array.isArray(val.value)&&val.value.length==0) continue;
              let valueDesc;

              if(val.inAdvSearchDialog && this.$refs.advSearchDialog.searchItems.length>0) {
                //页面载入时，advSearchDialog.searchItems还没有初始化，需要从后台传入中获得文字
                valueDesc = this.$refs.advSearchDialog.getItemDesc(k,val.value);
              } else {
                var temp = val.value;
                //如果是从本地localstorage载入，不要改变
                // debugger;
                if(val.inLocalStorage) temp = val.valueDesc;
                //对于popup-select会从后台传入text属性
                else if(val.sourceRemote && val.sourceRemote.text) temp=val.sourceRemote.text;
                valueDesc= temp;
              }
              ret.push({key:k,title:val.text,connector:':',value:val.value,valueDesc:valueDesc});
            }
            this.searchTags =ret;
            // dump('searchTags is build',this.searchTags);
            //将搜索条件保存到localstorage
            //如果高级弹窗组件没有从服务器获得，需要延迟到从服务器获得组件后保存，有些标题需要从组件配置信息中获得
            if(this.$refs.advSearchDialog.searchItems.length>0) {
              // dump('save local in watch')
              this._setSearchFromLocal();
            }

            this.showLoading = true;
            this._getRows();
          },
        }
      },
      //装载前初始化searchModel可以保证高级弹窗的获得最新的searchItems,否则会空
      beforeMount : function() {
        this.initSearchModel();
      },
      mounted: function() {
        window.test=this;
        // dump(this);
        // dump('root mounted');
        var that = this;
        window.onresize = function() {
          that.setTblHeight();
        }

        //隐藏遮罩
        // this.showLoading = false;

        var cols = this.getColsFromLocal();
        if(cols) {
          this.colNamesShow = cols;
        }

        //是否设置了操作按钮列
        var hasShowButton = false;
        for(var k in columns) {
          if(columns[k].showButton) {
            hasShowButton=true;
            break;
          }
        }
        //如果没有在后台定义操作按钮显示列,默认第一列显示操作按钮
        if(!hasShowButton) {
          if(this.editButtons.length>0) {
            console.warn('存在行操作按钮,但是未在列定义中发现可显示操作按钮的列,您需要将某列的showButton设置为true');
            this.columns[this.colNamesShow[0]].showButton=true;
          }
        }

        //载入sonTpl
        Common.setSontpl.apply(this,[varTemplate]);
      }
    };

    //动态载入系统级别组件,这里没有使用eval,是预载入，
    opt.components = {};
    //系统级别组件
    var arrComps = ['comp-table','comp-advsearch-dialog','comp-expand-tabs'];
    //用户级别组件:行编辑按钮中的自定义组件
    var arrCompsUser = [];
    for(var k in varTemplate.arr_field_info) {
      var f = varTemplate.arr_field_info[k];
      if(f.type=='component') {
        arrCompsUser.push(f.options.type);
      }
      if(!f.editButtons) continue;
      for(var i=0;f.editButtons[i];i++) {
        var btn = f.editButtons[i];
        if(btn.type!='comp') continue;
        arrCompsUser.push(btn.options.type);
      }
    }

    // var temp='';
    // for(var i=0;arrComps[i];i++) {
    //   temp = temp +`'${arrComps[i]}':resolve=>require(['_vue!pathComponent/${arrComps[i]}'], resolve),`;
    // }
    // // 下面的组件是comp-table中要用的组件,这里声明没什么用
    // // for(var i=0;arrCompsUser[i];i++) {
    // //   temp = temp +`'${arrCompsUser[i]}':resolve=>require(['_vue!pathComponentUser/${arrCompsUser[i]}'], resolve),`;
    // // }
    // opt.components = eval(`({${temp}})`);
    // // dump(opt,temp);
    // var app = new vue(opt);

    var temp=[];
    for(var i=0;arrComps[i];i++) {
      // temp = temp +`'${arrComps[i]}':resolve=>require(['_vue!pathComponent/${arrComps[i]}'], resolve),`;
      temp.push(`_vue!pathComponent/${arrComps[i]}`);
    }
    for(var i=0;arrCompsUser[i];i++) {
      // temp = temp +`'${arrComps[i]}':resolve=>require(['_vue!pathComponent/${arrComps[i]}'], resolve),`;
      // temp.push(`_vue!pathComponentUser/${arrCompsUser[i]}`);
      temp.push(`_vue!pathComponent/${arrCompsUser[i]}`);
    }
    require(temp,function(){
      for(var i=0;arrComps[i];i++) {
        var key = arrComps[i];
        opt.components[key] = arguments[i];
      }
      for(var j=i,k=0;arrCompsUser[k];j++,k++) {
        var key = arrCompsUser[k];
        opt.components[key] = arguments[j];
      }
      var app = new vue(opt);
      // window.app=app;
    });

  })
});


